package gameManager;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

public class GameManager {
    private LevelList myLevelList = new LevelList();
    private Level currentLevel = null;
    final String LEVEL_CLASS_DIRECTORY = "gameManager.";
    private int score;
    private List<Interactable> interactableCharacters = new ArrayList<Interactable>();
    private PlayerCharacter playerCharacter;
    
    public List<String> getLevels() {
        return myLevelList.getLevels();
    }
    
    public void setLevel(String level) {
        Constructor levelConstructor = null;
        try {
            levelConstructor = Class.forName(LEVEL_CLASS_DIRECTORY + level).getConstructor();
        }
        catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        catch (SecurityException e) {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        try {
            currentLevel = (Level) levelConstructor.newInstance();
        }
        catch (InstantiationException | IllegalAccessException
                | IllegalArgumentException | InvocationTargetException e) {
            e.printStackTrace();
        }     
    }
    
    public void initializePlayerCharacter() {
        //create the player character
        interactableCharacters.add(playerCharacter);
        Dimension backgroundDimension = new Dimension(getBackgroundImage().getWidth(null), getBackgroundImage().getHeight(null));
        playerCharacter.setBackgroundDimension(backgroundDimension);
    }
    
    public Level getCurrentLevel() {
        return currentLevel;
    }
    
    public int getScore() {
        return score;
    }
    public void updateScore(int dScore) {
        score += dScore;
    }
        
    
    public void update(int trigger) {
            addNewInteractableCharacters(trigger, currentLevel);
            updateInteractableCharacters(trigger);
            destroyInteractableCharacters();
    }

    public void addNewInteractableCharacters(int trigger, Level currentLevel) {
        interactableCharacters.addAll(currentLevel.createNonPlayerCharacter(trigger));
    }
    
    public void updateInteractableCharacters(int trigger) {
        for (Interactable character : interactableCharacters) {
            character.update(trigger);
        }
    }
    
    public void collisionDetection() {
        for (Interactable characterOne : interactableCharacters) {
            for (Interactable characterTwo : interactableCharacters) {
                if (collide(characterOne, characterTwo)) {
                    characterTwo.collisionHandler(characterOne);
                }
            }
        }
    }
    
    public boolean collide (Interactable characterOne, Interactable characterTwo) {
        return (characterTwo.getNamesOfInteractableCanCollideWith().contains(characterOne.getNameOfInteractable())
                && ((characterOne.getDimension().width + characterTwo.getDimension().width) / 2 
                < Math.abs(characterOne.getCenter().x - characterTwo.getCenter().x))
                && ((characterOne.getDimension().height + characterTwo.getDimension().height) / 2 
                        < Math.abs(characterOne.getCenter().y - characterTwo.getCenter().y))
                && characterOne != characterTwo);
    }
    
    public boolean checkOutBound(Interactable character) {
        return (character.getCenter().x + character.getDimension().width / 2 < 0
                || character.getCenter().x - character.getDimension().width / 2 > getBackgroundImage().getWidth(null)
                || character.getCenter().y + character.getDimension().height / 2 < 0
                || character.getCenter().y - character.getDimension().height / 2 > getBackgroundImage().getHeight(null));
    }
    
    public void destroyInteractableCharacters() {
        for (Interactable character : interactableCharacters) {
            if (character.isDying()) {
                character.destroy();
                interactableCharacters.remove(character);
            }
        }
    }

    public List<Interactable> getInteractableObjects() {
        return interactableCharacters;
    }
    
    public PlayerCharacter getPlayerCharacter() {
        return playerCharacter;
    }
    
    public Image getBackgroundImage() {
        return currentLevel.getBackgroundImage();
    }

    public void keyPressed(KeyEvent e) {
        
    }
    
    public void keyReleased(KeyEvent e) {
        
    }
}
